﻿using System.Linq;
using ff14bot;
using ff14bot.Behavior;
using ff14bot.Enums;
using ff14bot.Managers;
using ff14bot.Objects;
using TreeSharp;

namespace Magitek.Helpers
{
    public class Combat
    {
        public static BattleCharacter MultiDotTarget(string dot)
        {
            var target = GameObjectManager.GetObjectsOfType<BattleCharacter>()
                .Where(x => x.CanAttack && x.IsAlive && x.HasTarget && Actionmanager.CanCast(dot, x) && !x.HasAura(dot, true))
                .OrderByDescending(x => x.CurrentHealthPercent)
                .FirstOrDefault();

            if (target == null)
            {
                return null;
            }

            return target;
        }

        public static Composite CreatePull(float range)
        {
            return new PrioritySelector(ctx => Core.Player.CurrentTarget,
                Extensions.EnsureTarget,
                new Decorator(ctx => ctx != null,
                new PrioritySelector(
                new Decorator(r => BotManager.Current.IsAutonomous, new PrioritySelector(
                CommonBehaviors.MoveToLos(ctx => ctx as GameObject),
                CommonBehaviors.MoveAndStop(ctx => (ctx as GameObject).Location, ctx => range, true, "[Magitek] Moving in Range"))),
                  Casting.Cast(r => BestPullSpell, r => Actionmanager.InSpellInRangeLOS(BestPullSpell, Core.Target) == SpellRangeCheck.Success, r => Core.Target, r => 3, r => true)
              )));
        }

        private static string[] PullSpells = new[] { "Fire", "Piercing Talon", "Fast Blade", "Shield Lob", "Straight Shot", "Heavy Swing", "Bootshine", "True Thrust", "Heavy Thrust", "Blizzard", "Ruin", "Stone", "Heavy Shot" };
        private static string _BestPullSpell;
        private static string BestPullSpell
        {
            get
            {
                if (string.IsNullOrEmpty(_BestPullSpell))
                {
                    foreach (var spell in PullSpells)
                    {
                        if (Actionmanager.HasSpell(spell))
                        {
                            _BestPullSpell = spell;
                            return spell;
                        }
                    }

                    return null;

                }
                else
                {
                    return _BestPullSpell;
                }
            }
        }

        public static bool CheckForInterrupt()
        {
            SpellCastInfo info = ((BattleCharacter)Core.Player.CurrentTarget).SpellCastInfo;

            if (Magitek.WindowSettings._interruptList.Count == 0)
                return false;

            if (Magitek.WindowSettings._interruptList.Contains(info.SpellData.Name))
            {
                return true;
            }
            return false;
        }

        public static GameObject ProvokeTarget() { return GameObjectManager.GetObjectsOfType<BattleCharacter>().Where(u => u.IsValid && u.IsVisible && u.CanAttack && u.Location.Distance(Core.Player.Location) < 20).OrderBy(p => p.CurrentTargetId != Core.Player.ObjectId).FirstOrDefault(); }

        public static Composite DoPVPHealing()
        {
            return new Decorator(r =>
            {
                if (!PartyManager.IsInParty || !Magitek.WindowSettings.DoPVP)
                    return false;

                return true;

            }, new PrioritySelector(
                
                //   Casting.Cast(r => "Purify", r => true, r => Core.Player.CurrentTarget, r => 2, r => false),
                Casting.Cast(r => "Attunement", r => Magitek.WindowSettings.pvpAttunement && Core.Player.CurrentHealthPercent <= Magitek.WindowSettings.pvpAttunementHpPercent, r => Core.Player, r => 2, r => false),
                Casting.Cast(r => "Mana Draw", r => Magitek.WindowSettings.pvpManaDraw && Core.Player.CurrentManaPercent <= Magitek.WindowSettings.pvpManaDrawMpPercent, r => Core.Player.CurrentTarget, r => 2, r => false),
                Casting.Cast(r => "Equanimity", r => Magitek.WindowSettings.pvpEquanimity && Core.Player.InCombat && GameObjectManager.GetObjectsOfType<BattleCharacter>().Any(u => u.InLineOfSight() && u.CurrentTargetId == Core.Player.ObjectId && u.CanAttack), r => Core.Player, r => 2, r => false),
                Casting.Cast(r => "Sacred Prism", r => Magitek.WindowSettings.pvpSacredPrism && PartyHelper.PeopleNeedingHealsAroundTarget(75, PartyHelper.Healtarget) >= Magitek.WindowSettings.TargetsToAOEHeal, r => Core.Player.CurrentTarget, r => 2, r => false),
                Casting.Cast(r => "Divine Breath", r => Magitek.WindowSettings.pvpDivineBreath && PartyHelper.Deadtarget != null && Magitek.WindowSettings.lastspellused != "Swiftcast" && !Core.Player.HasAura("Swiftcast"), r => PartyHelper.Deadtarget, r => 2, r => false),
                Casting.Cast(r => "Focalization", r => Magitek.WindowSettings.pvpFocalization && Core.Player.InCombat && PartyHelper.PeopleNeedingHealsAroundTarget(80, Core.Player) >= Magitek.WindowSettings.TargetsToAOEHeal, r => Core.Player, r => 2, r => false)
                ));
        }

        public static Composite DoPVP()
        {
            return new Decorator(r =>
            {
                if (!PartyManager.IsInParty || !Magitek.WindowSettings.DoPVP)
                    return false; 

                return true;

            }, new PrioritySelector(

                Casting.Cast(r => "Purify", r => Magitek.WindowSettings.pvpPurify && NeedCCBreak, r => Core.Player.CurrentTarget, r => 2, r => false),
                Casting.Cast(r => "Fetter Ward", r => Magitek.WindowSettings.pvpFetterWard && IsSomeoneTryingToCCMe, r => Core.Player, r => 2, r => false),


                Casting.Cast(r => "Night Wing", r => Magitek.WindowSettings.pvpNightWing && Extensions.EnemiesNearTarget(5) >= 3, r => Core.Player.CurrentTarget, r => 2, r => false),

                Casting.Cast(r => "Enliven", r => Magitek.WindowSettings.pvpEnliven && Core.Player.CurrentTPPercent <= 50, r => Core.Player, r => 2, r => false),
                Casting.Cast(r => "Blast Shot", r => Magitek.WindowSettings.pvpBlastShot && Extensions.EnemiesNearTarget(5) >= 2, r => Core.Player.CurrentTarget, r => 2, r => false),
                Casting.Cast(r => "Farshot", r => Magitek.WindowSettings.pvpFarshot, r => Core.Player.CurrentTarget, r => 2, r => false),

                Casting.Cast(r => "Manasong", r => Magitek.WindowSettings.pvpManaSong && PartyManager.VisibleMembers.Any(u => (u.Class.ToString() == "WhiteMage" || u.Class.ToString() == "Scholar") && (u.GameObject as BattleCharacter).CurrentManaPercent <= 75 && u.GameObject.Distance(Core.Player.Location) <= 15), r => Core.Player, r => 2, r => false),
                Casting.Cast(r => "Mana Draw", r => Magitek.WindowSettings.pvpManaDraw && Core.Player.CurrentManaPercent <= Magitek.WindowSettings.pvpManaDrawMpPercent, r => Core.Player, r => 2, r => false),

                Casting.Cast(r => "Mythril Tempest", r => Magitek.WindowSettings.pvpMythrilTempest && Extensions.EnemiesNearPlayer(5) >= Magitek.WindowSettings.pvpEnemiesToAOE, r => Core.Player, r => 2, r => false),
                Casting.Cast(r => "Thrill of War", r => Magitek.WindowSettings.pvpThrillOfWar && Core.Player.CurrentHealthPercent >= 70, r => Core.Player, r => 2, r => false),

                Casting.Cast(r => "Tetsudo", r => Magitek.WindowSettings.pvpTetsudo && PartyHelper.Tetsudotarget != null, r => PartyHelper.Tetsudotarget, r => 2, r => false),
                Casting.Cast(r => "Glory Slash", r => Magitek.WindowSettings.pvpGlorySlash, r => Core.Player.CurrentTarget, r => 2, r => false),
                Casting.Cast(r => "Full Swing", r => Magitek.WindowSettings.pvpFullSwing, r => Core.Player.CurrentTarget, r => 2, r => false),

                Casting.Cast(r => "Axe Kick", r => Magitek.WindowSettings.pvpAxeKick && Extensions.EnemiesNearPlayer(5) >= Magitek.WindowSettings.pvpEnemiesToAOE, r => Core.Player, r => 2, r => false),
                Casting.Cast(r => "Somersault", r => Magitek.WindowSettings.pvpSomersault, r => Core.Player.CurrentTarget, r => 2, r => false),

                Casting.Cast(r => "Impulse Rush", r => Magitek.WindowSettings.pvpImpulseRush, r => Core.Player.CurrentTarget, r => 2, r => false),

                Casting.Cast(r => "Weapon Throw", r => Magitek.WindowSettings.pvpWeaponThrow && Core.Player.CurrentTarget.IsBehind && Core.Player.CurrentTarget.HasAura("Sprint"), r => Core.Player.CurrentTarget, r => 2, r => false),
                Casting.Cast(r => "Skewer", r => Magitek.WindowSettings.pvpSkewer, r => Core.Player.CurrentTarget, r => 2, r => false),

                Casting.Cast(r => "Phantom Dart", r => Magitek.WindowSettings.pvpPhantomDart, r => Core.Player.CurrentTarget, r => 2, r => false),

                Casting.Cast(r => "Misty Veil", r => Magitek.WindowSettings.pvpMistyVeil, r => Core.Player.CurrentTarget, r => 2, r => false),
                Casting.Cast(r => "Wither", r => Magitek.WindowSettings.pvpWither, r => Core.Player.CurrentTarget, r => 2, r => false),

                Casting.Cast(r => "Aetheric Burst", r => Magitek.WindowSettings.pvpAethericBurst && Extensions.EnemiesNearPlayer(5) >= Magitek.WindowSettings.pvpEnemiesToAOE, r => Core.Player, r => 2, r => false),

                Casting.Cast(r => "Aura Blast", r => Magitek.WindowSettings.pvpAuraBlast && Extensions.EnemiesNearPlayer(5) >= Magitek.WindowSettings.pvpEnemiesToAOE, r => Core.Player, r => 2, r => false)
               
            ));
        }

        public static bool IsCrowdControlled(GameObject target)
        {
            if (target.HasAura("Sleep") || target.HasAura("Stun") || target.HasAura("Bind"))
                return true;

            return false;
        }

        private static bool IsSomeoneTryingToCCMe
        {
            get
            {
                return GameObjectManager.GetObjectsOfType<BattleCharacter>()
                    .Any(u => u.InLineOfSight() && u.CurrentTargetId == Core.Player.ObjectId && u.IsCasting && Magitek.WindowSettings._pvpCCbreakList.Contains(u.SpellCastInfo.Name));
            }
        }

        public static bool NeedCCBreak
        {
            get { return Core.Player.CharacterAuras.Any(u => Magitek.WindowSettings._pvpCCbreakList.Contains(u.Name)); }
        }
    }
}
